#!/usr/bin/perl -w
#Reformatting MSS of 1 John into a common format

use strict;
use warnings;
use utf8;
#use encoding "utf8", STDIN => 'utf8', STDOUT => 'utf8';
use open ':encoding(utf8)';
use Algorithm::Diff;
use Unicode::Normalize qw(decompose);
use XML::LibXML;

my $count = 0;
my $parser = XML::LibXML->new();
my $greekXML = $parser->parse_file( "../strongs-dictionaries/StrongsGreek-2008-12-31/strongsgreek.xml" ) or die "Can't get strongsgreek.xml";
my $line;

=thoughts

So what we'll do is iterate over each of the source texts and work to combine them
all into one unified manuscript.  Each manuscript (and sub-manuscripts) must have unique IDs to identify them.
Actually, for the unified MS, we will want to just create a raw list of words without any
regard for variants. What if variants are presented in different orders? We'll need to
create different text files for each MS and each variant set? In the TR we have,
each variant is associated with a specific edition, but as with the UBS, there may
be many variants included, but they are deemed less good. This may be out of scope.

So we're working with flat texts as with MorphGNT.

Format of the unified text file:
REF STRONGS WORD (PARSING)


=cut

##################################################################
# MorphGNT
##################################################################

print ++$count . ". ccat-tauber-morphgnt-v5_08...";
chdir 'ccat-tauber-morphgnt-v5_08';
open IN, "ccat-tauber-morphgnt-v5_08-utf8.txt"
	or die "Dir ccat-tauber-morphgnt-v5_08 doesn't exist.";
open OUT, ">1john.morphgnt.txt";
$line = 0;
while(<IN>){
	next if !/^23/; #is 1 John
	$line++;
	s/^(\d\d)(\d\d)(\d\d) \S\S \S+ //;
	my $book = $1 + 39;
	my $chapter = $2;
	my $verse = $3;
	s/ (\S+)?$//;
	#my $lemma = $1;
	s/\r?\n$//;
	my $word = $_;
	
	print OUT formatWordLine(book => $book,
							 chapter => $chapter,
							 verse => $verse,
							 word => $word
							);
}
close IN;
close OUT;
chdir '..';
print "done\n";


##################################################################
# Tischendorf
##################################################################

print ++$count . ". Tischendorf-2.5...";
chdir 'Tischendorf-2.5';
open IN, "Tischendorf-2.5/Unicode/1JO.txt"
	or die "Dir Tischendorf-2.5 doesn't exist.";
open OUT, ">1john.tisc.txt";
while(<IN>){
	my %args = ();
	s/^1JO (\d+):(\d+)\.(\d+) ([\.CP])// or die "Parse error in Tisch";
	$args{book} = 23;
	$args{chapter} = $1;
	$args{verse} = $2;
	$args{punctuation} = $4;
	
	#$tisc =~ m/^.+?\s+(.+?)[\.;]?(?=,|\s)/;
	
	/^.+?\s+(.+?)[\.;]?(?=,|\s)/ or die "Coudldn't get word";
	$args{word} = $1;
	
	/\b(\d+)\b/ or die "Couldn't get Strong's";
	$args{strongs} = $1;
	
	#print OUT formatWordLine($book, $chapter, $verse, $word, $strongs);
	print OUT formatWordLine(%args);
}

close OUT;
close IN;
chdir '..';
print "done\n";

##################################################################
# Greek NT: Textus Receptus (1550/1894) [Parsed]
# The Textus Receptus with complete parsing information for all Greek words; base text is Stephens 1550, with variants of Scrivener 1894.
##################################################################

print ++$count . ". greek_textus_receptus_parsed...";
chdir 'greek_textus_receptus_parsed'
   or die "Dir greek_textus_receptus_parsed doesn't exist.";
open IN, 'greek_textus_receptus_parsed_utf8.txt';

open STEPHENS, ">1john.tr-stephens.txt";
open SCRIVENER, ">1john.tr-scrivener.txt";
while(<IN>){
	next if !/^62N\t/; #is 1 John
	s/^(\d+)(\w)\t+(\d+)\t+(\d+)\t+\d+\t+//;
	chomp;
	s/\r//g;
	
	my $group = $2;
	my $book = $1;
	my $chapter = $3;
	my $verse = $4;
	
	my $original = $_;
	formatUnboundSelectingVariant(1, $book, $chapter, $verse);
	print STEPHENS;
	
	$_ = $original;
	formatUnboundSelectingVariant(2, $book, $chapter, $verse);
	print SCRIVENER;
}
close IN;
close STEPHENS;
close SCRIVENER;
chdir '..';
print "done\n";


##################################################################
# Greek NT: Westcott/Hort, UBS4 variants [Parsed]
# The Westcott-Hort edition of 1881 with complete parsing information for all Greek words.
# Readings of Nestle-Aland 27th/UBS4 shown, also with complete parsing information attached.
# {VAR1: Refers to Westcott-Hort}
# {VAR2: Refers to Nestle-Aland 27th/UBS4}
##################################################################

print ++$count . ". greek_WH_UBS4_parsed...";
chdir 'greek_WH_UBS4_parsed'
   or die "Dir greek_WH_UBS4_parsed doesn't exist.";
open IN, 'greek_WH_UBS4_parsed_utf8.txt';

open WH, ">1john.wh.txt";
open UBS4, ">1john.ubs4.txt";
while(<IN>){
	next if !/^62N\t/; #is 1 John
	s/^(\d+)(\w)\t+(\d+)\t+(\d+)\t+\d+\t+//;
	chomp;
	s/\r//g;
	
	my $group = $2;
	my $book = $1;
	my $chapter = $3;
	my $verse = $4;
	
	my $original = $_;
	formatUnboundSelectingVariant(1, $book, $chapter, $verse);
	print WH;
	
	$_ = $original;
	formatUnboundSelectingVariant(2, $book, $chapter, $verse);
	print UBS4;
}
close IN;
close WH;
close UBS4;
chdir '..';
print "done\n";

##################################################################
# Greek NT: Byzantine/Majority Text (2000) [Parsed]
# The Greek New Testament according to the Byzantine Textform, edited by Maurice A. Robinson and
# William G. Pierpont, 2000 edition This is the edition by Pierpont and Robinson of a Majority, or
# Byzantine, text of the NT. It is similar to an earlier production of Hodges and Farstad in being
# based on von Soden's apparatus, but without their stemmatic reconstruction of the Apocalypse and the Pericope Adulterae.
##################################################################


print ++$count . ". greek_byzantine_2000_parsed...";
chdir 'greek_byzantine_2000_parsed'
   or die "Dir greek_byzantine_2000_parsed doesn't exist.";
open IN, 'greek_byzantine_2000_parsed_utf8.txt';

open OUT, ">1john.b-mt.txt";
while(<IN>){
	next if !/^62N\t/; #is 1 John
	s/^(\d+)(\w)\t+(\d+)\t+(\d+)\t+\d+\t+//;
	chomp;
	s/\r//g;
	
	my $group = $2;
	my $book = $1;
	my $chapter = $3;
	my $verse = $4;
	
	formatUnboundSelectingVariant(undef, $book, $chapter, $verse);
	print OUT;
}
close IN;
close WH;
close UBS4;
chdir '..';
print "done\n";



###################################################################################

use Data::Dumper;


sub formatUnboundSelectingVariant {
	my $varNum = shift;
	my $book = shift;
	my $chapter = shift;
	my $verse = shift;

	#Keep only the requested variant
	if($varNum){
		s/{VAR$varNum:(.+?)}/$1/g;
		s/{VAR(?!$varNum)\d+:(.+?)}//g;
	}
	
	#Trim
	s/^\s+//;
	s/\s+$//;
	
	s/
		(\[(?!\s)\b\p{Greek}+.+?\p{Greek}\b(?<!\s)\])
	 /
		addVariantBrackets($1)
	 /gxe;
	
	#Parse multiple words on a line
	s/
		\s*(\[?\p{Greek}+\]?)
		\s+G(0*\d+)
		\s+([A-Z\ 0-9\-]+?)
		(?=\s+\[?\p{Greek}|\s*$|\s*{)
	 /
		formatWordLine(book => $book,
					   chapter => $chapter,
					   verse => $verse,
					   word => $1,
					   strongs => $2,
					   parsing => $3)
	 /gex;
}

sub addVariantBrackets {
	my $s = shift;
	
	$s =~ s/
		(?<!\[)(\b\p{Greek}+)
	 /\[$1/gx;
	
	$s =~ s/
		(\p{Greek}+\b)(?!\])
	 /$1\]/gx;
	 
	 
	#s/(?<!\[)(?=\b\p{Greek}+)/\[/g;
	
	#s/(\[\p{Greek}+)\b(?!\])/$1]/g;
	#s/(?<!\[)(\b\p{Greek}+\b\])/[$1/g;
	
	return $s;
}


sub formatWordLine {
	%_ = @_;
	$_{strongs} ||= '';
	
	$_{word} = decompose($_{word});
	$_{word} =~ s/  ' | ’  |  \p{IsDiacritic}  //gx;
	$_{word} = lc $_{word};
	
	#Remove brackets so we can do diffs better
	$_{word} =~ s/^\[//;
	$_{word} =~ s/\]$//;
	
	return sprintf("%s\n", $_{word});
	#return sprintf("%02d:%02d %s\n", $_{chapter}, $_{verse}, $_{word});
	#return sprintf("%02d:%02d G%04d %s\n", $chapter, $verse, $strongs, $word);
	#return sprintf("%02d:%02d:%02d G%04d %s\n", $book, $chapter, $verse, $strongs, $word);
	#return sprintf("%02d:%02d:%02d G%04d %s\n", $book, $chapter, $verse, $word, $strongs);
	#return sprintf("%02d:%02d:%02d %s\n", $book, $chapter, $verse, $word);
}

my %strongsLookup;
sub getStrongs {
	foreach(@_){
		return $strongsLookup{$_} if exists $strongsLookup{$_};
		
		my $strongs = 0;
		#my $entry = $greekXML->find("/strongsdictionary/entry[ ./greek[\@unicode = \"$_\" and preceding-sibling::preceding-sibling[local-name() = 'strongs'] ] ]");
		my $entry = $greekXML->find("/strongsdictionary/entries/entry[ ./greek[\@unicode = \"$_\" ] ]");
		
		if(!$entry->size()){
			
			#return "¿$_?";
			
			if($_ eq "ἐπαγγέλλομαι"){
				$strongs = 1861;
			}
			elsif($_ eq "παρρησία"){
				$strongs = 3954;
			}
			else {
				warn "Can't find! $_\n";
				next;
			}
		}
		else {
			$strongs = int $entry->get_node(1)->getAttribute('strongs');
		}
		$strongsLookup{$_} = $strongs;
		return $strongsLookup{$_};
	}
	
	return 0;
}

#sub addVarMeta {
#	my $text = shift;
#	my $varNum = shift;
#	
#	$text =~ s{(?<=\p{Greek} )(?=\b[GH]\d+)}
#	          {VAR$varNum }g;
#	
#	return $text;
#}